PATH
MacOS X Server Release Notes Copyright \xa9 1998 by Apple Computer, Inc. All Rights Reserved.
If the same breakpoint is hit simultaneously (or near-simultaneously) by multiple threads within a process being debugged, GDB is unable to handle the race condition that develops among the multiple exceptions to be handled.
This will typically lead to GDB stopping at unexpected locations in the inferior with a SIGTRAP (rather than a breakpoint) --- typically a thread other than the current thread will be at the breakpoint address, and GDB will be showing the leftover exception from the other thread hitting the breakpoint.
Occasionally, multiple threads hiting the same breakpoint can lead to overall system instability, including hanging GDB, creating un-killable processes, and sending SIGTRAP signals to un-related processes.
GDB hangs (actually, the new Sybase CT-Lib adaptor blocks) when you use the next
command to step over a line of code which eventually causes a call to the Sybase client library.
More generally, when you are debugging a program that uses multiple threads it's possible to create a situation in which a deadlock will occur. Whenever the next
or step
commands are issued, GDB lets only the thread being debugged execute. All other threads are suspended until the command is completed. Therefore, if you attempt to step over a line of code which tries to communicate with another thread, the program will deadlock.
To deal with problems like this, a "run-all-threads" option has been added to gdb. This option controls whether all of the threads should execute while single-stepping. The default value for this option is "off". In order to prevent a deadlock like that described above, issue the following command in gdb:
set run-all-threads on
We recommend that you use this option only if you're experiencing a deadlock. Allowing other threads to execute while stepping through code can produce confusing results if, for example, the other threads are changing the values of global data.
GDB has been known to hang or crash if you run a program that uses a dynamic shared library (such as a framework or bundle), then recompile the dynamic shared library, and run the program again. If this happens, you should quit GDB and start a new debugging session every time you rebuild the library. You can use the .gdbinit file to help re-establish things such as breakpoints that you need in your debugging session.
Immediately after you start your program running under gdb, the program will start to load dynamic shared libraries, and GDB will begin reading symbols from these libraries. If you attempt to interrupt GDB by typing Control-C during this process, the debugger will be left in a confused internal state from which the only known recovery is to quit the debugger and start over.
When GDB debugs code without debugging symbols, it assumes variables are of size sizeof(int)
. Setting or displaying a BOOL (or any non-int) value will usually lead to incorrect results. In particular, setting a BOOL value will cause the next three bytes of memory to be overwritten. For example, if you have four BOOL values declared, setting the first one will cause the next three to acquire unexpected values. Of course, if you have only one BOOL variable and you set it, whatever is next to it in memory is likely to get trashed. This problem does not occur in code containing debugging symbols as GDB knows exactly how big the variable in question is.
This problem prevents setting the global debugging variables declared in Foundation for debugging Objective-C programs; see NSDebug.h
for more information. The workaround for this problem is to set the debugging variables via the command-line or via the environment.
start()
Due to the way that gdb-4.14 interacts with the dynamic link editor at startup, there is always a breakpoint inserted at start() + 24
. It is there to avoid a particularly nasty race condition that prevents gdb-4.14 from talking to the dynamic link editor properly. After gdb-4.14 stops at this breakpoint, you must continue the target.
gdb-4.14 can sometimes get confused when its target process creates a child process and that child process crashes. gdb-4.14 will sometimes incorrectly report that the parent process has crashed.
The Objective-C runtime system catches when messages are sent to some freed Objective-C objects; when this happens, a message like this appears in your console:
objc: FREED(id): message XXX sent to freed object=0x13d938
The runtime system calls abort()
. In this case however, gdb-4.14 is unable to print the backtrace beyond the third stack frame. Thus it is not possible to determine the backtrace which resulted in sending the message to a freed object. The workaround is to set a breakpoint at _freedHandler
, which is a function in the Objective-C runtime. This breakpoint is hit just before the call to abort()
and gdb-4.14 can provide a valid backtrace.
tl
command on core fileAlthough gdb-4.14 has support for viewing multiple threads from a dumped core image, the tl
command will currently cause a fatal error in gdb-4.14 (typically a segmentation fault). To work around this problem, use the ts
command to switch threads without using tl
. The threads will be numbered from 0
upward; gdb-4.14 will print no such thread
when the last thread has been reached.
When attaching to an already-running process, gdb-4.14 will crash if the program has loaded any bundles or shared libraries beyond those with which it was linked at compile-time. Examples of such programs include ProjectBuilder, InterfaceBuilder, and many Java applications.
The PowerPC runtime conventions require that the PowerPC stack be aligned to a 16-byte boundary at all times. Unfortunately, there are certain Foundation libraries which appear to violate this requirement for limited periods of time.
If gdb-4.14 attempts to call any functions in the inferior (including Objective-C method lookups) when the stack is not aligned to a 16-byte boundary, a fatal assertion failure ((*sp % MINIMUM_STACK_ALIGNMENT) == 0)
will be generated.
Each time the inferior program is run, gdb-4.14 will automatically re-load all of the libraries used by the program. This is wasteful in time as well as in memory, as gdb-4.14 has no way to remove the symbols from the previously loaded libraries. Additionally, if the memory address of any library is changed from one run of the program to another, gdb-4.14 will be unable to remove the old symbols, and may incorrectly use the old values of the symbols in place of the new ones.
In some frameworks, DYLD lazy function pointer tables appear in the executable after the shared library symbol stubs, rather than before them, leading to a negative offset from the stub entry to the lazy pointer. gdb-4.14 fails to properly sign-extend this negative offset, causing it to be unable to determine the target of a shared library stub call. This can often lead to gdb-4.14 inadvertently continuing the process while trying to single-step through code contained in a framework that makes calls to other functions in that framework.